#include <sys/types.h> 
#include <sys/time.h> 
#include <stdlib.h> 
#include <err.h>  
#include <event.h> 
#include <evhttp.h>  
#include <sys/queue.h>

#include "redisop.h"

CRedisOp    CReOp;

char szCrossXml[] = "<?xml version=\"1.0\"?> \
<cross-domain-policy> \
<allow-access-from domain=\"*\" to-ports=\"*\" /> \
</cross-domain-policy>";

int RedOpInit()
{
    bool bRet = false;

    ServerInfo  sinfo; // redis server info
    memcpy( sinfo.szIp, "127.0.0.1", 9 );
    sinfo.iPort = 6379;

    bRet = CReOp.Init( (void*)&sinfo ); // set redis server arguments
    if( !bRet )
    {
        printf( "init Redis server error.\n" );
        return -1;
    }

    return 0;
}

char * query_memorydb(const char * szKey, int & iBufLen)
{
    char * szVal = NULL;

    iBufLen = CReOp.GetResult( szKey, &szVal );

    return szVal;
}

void root_handler(struct evhttp_request *req, void *arg) 
{         
    struct evbuffer *buf;          

    buf = evbuffer_new();         
    if (buf == NULL)                 
        err(1, "failed to create response buffer");         

    evbuffer_add_printf(buf, "red test print!\n");         

    evhttp_send_reply(req, HTTP_OK, "OK", buf); 
}  

void generic_handler(struct evhttp_request *req, void *arg) 
{      
    struct evbuffer *evb = NULL;          
	const char *uri = evhttp_request_get_uri(req);

    evb = evbuffer_new();         
    if (evb == NULL)                 
       err(1, "failed to create response buffer");         

    struct evkeyvalq front_headers;
    int iValueLen = 0;
    char * szIdValue = NULL;

    TAILQ_INIT(&front_headers);

    //process flash cross xml file
    if( strcmp(uri, "/crossdomain.xml") == 0 ) 
    {
        evbuffer_add( evb, (const void *)szCrossXml, strlen(szCrossXml) ); 
        evhttp_send_reply(req, HTTP_OK, "OK", evb); 
    }
    else
    {
        //arguments process
        int iParseRet = evhttp_parse_query(uri, &front_headers);
        const char * szIdKey = evhttp_find_header( &front_headers, "id" );
        if( szIdKey==NULL )
        {
            printf( "argument id not find." );
            evhttp_send_error(req, 404, "Document was not found");
        }
        else
        {

            szIdValue = query_memorydb( szIdKey, iValueLen );
            if( szIdValue==NULL )
            {
                printf( "get key value fail." );
                evhttp_send_error(req, 404, "Document was not found");
            }
            else
            {
            evbuffer_add( evb, (const void *)szIdValue, iValueLen ); 

            evhttp_send_reply(req, HTTP_OK, "OK", evb); 
            }
        }
    }

	if (evb)
		evbuffer_free(evb);

    evhttp_clear_headers(&front_headers);
}  

int main(int argc, char **argv) 
{         
    struct evhttp *httpd;          
    event_init();         

    unsigned short iPort = 9601;

    httpd = evhttp_start("0.0.0.0", iPort);          
    /* Set a callback for requests to "/". */         
    //evhttp_set_cb(httpd, "/", root_handler, NULL);          
    /* Set a callback for all other requests. */         

// 设置请求超时时间
//
// evhttp_set_timeout(httpd, timeout);

    RedOpInit();

    evhttp_set_gencb(httpd, generic_handler, NULL);          

    event_dispatch();          
    /* Not reached in this code as it is now. */          

    evhttp_free(httpd);          

    return 0;
}
